
#ifndef PNJ_H
#define PNJ_H

#include <iostream>
#include <string>
#include <SFML/Graphics.hpp>

#include "var_define.h"
#include "MoveAnim.h"
#include <pthread.h>


/*! \file Pnj.h
\brief La spécification de la classe Pnj
Décrit la liste des méthodes et attributs associés à la classe Pnj
\author Kleb - Tous Droits Réservés
\date 05/10/2011
*/
/*! \class Pnj
\brief La classe représentant les Pnj.
Cette Classe représente les Personnages Non Joueurs (PNJ) sous la forme d'un objet
une variable de type Pnj.
Cette classe possède les méthodes suivantes:
\li getName
\li getSurname
\li getFace
\li getMovement
\li getPositionX
\li int getPositionY
\li void setName
\li setSurname
\li setFace
\li setMove
\li setPosition
\li askAnim
\li threadRunAnimAnim
\li runAnim
*/

using namespace std;
using namespace sf;
class Pnj
{
    /* Attributs */
    protected:

    /*! \var string name
\brief Contient le nom du Pnj.
    */
        string name;

        /*! \var string surname
\brief Contient le prénom du Pnj.
*/
        string surname;

         /*! \var Image imgPnjHead
\brief Contient l'image de la tête du Pnj.
*/
        Image imgPnjHead;

        /*! \var Image canMove
\brief Booléen qui indique si le Pnj peut se déplacer ou reste statique
*/
        bool canMove;

        /*! \var Image imgPnjMovement
\brief Contient l'image représentant les mouvements du Pnj.
*/
        Image imgPnjMovement;

    /*! \var Sprite pnjHead
\brief Contient le Sprite de la tête du Pnj qui pointe sur la vaariable imgPnjHead contenant l'image.
*/
        Sprite pnjHead;

        /*! \var Sprite pnjMovement
\brief Contient le Sprite représentant les mouvements du Pnj, qui pointe sur la variable imgPnjMovement, contenant l'image.
*/
        Sprite movement;


 /*! \var Animùation anim
\brief Instance de la classe Animation qui permets de déplacer le Pnj.
*/
       MoveAnim moveAnim;

        /*! \var pthread_t thread
\brief Thread qui va gérer les déplacement du personnage en concurrence avec l'application.
*/
       pthread_t thread;

         /*! \var bool isMoving
\brief Booléen qui rensigne sur l'état du Pnj (si le thread est en train de déplacer le Pnj ou non).
*/
       bool isMoving;

       int caseX;
       int caseY;


            /*! \fn   static void* threadRunAnim(void* pnj)
\brief Fonction de Classe qui prends en paramètre le Pnj à déplacer, et lance la fonction runAnim() de cet objet.
Cette fonction est privée est ne peut etre appellée que par la fonction askAnim(int d) d'une instance de la classe Pnj.
\param pnj : Instance de la classe Pnj, castée en (void*) pour etre passée dans le Thread.
*/
        static void* threadRunAnim(void* pnj);

                /*! \fn   runAnim()
\brief Lance l'animation de mouvement du Pnj.
Cette fonction est privée et ne peut etre appelée que par la fonction de Thread, car il n'y a aucun élément d'affichage pendant les calculs de l'animation.
La direction étant déjà conservée dans l'instance d'Animation anim, il est inutile de le redemander.
*/
        void runAnim();


    public:
    /*! \fn Pnj()
\brief Constructeur par défaut de la classe Pnj
Ce constructeur donne un nom et un prénom par défaut, crée une instance par défaut de anim
fixe les images par défauts et met les booléen isMoving a false;
*/
        Pnj();

         /*! \fn Pnj(string n, string s, string f, string m)
\brief Constructeur de la classe Pnj
Ce constructeur fice le nom et prénom du Pnj, ainsi que les images qui lui sont associés.
anim est instancié par défaut et isMoving est mis a false.
\param n - Nom du Pnj (name)
\param s - Prenom du Pnj (surname)
\param f - lien sur l'image représentant l'apparence du Pnj
\param m - lien sur l'image représentant les mouvements du Pnj
*/
        Pnj(string n, string s, string f, string m);

         /*! \fn ~Pnj()
\brief Destructeur de la classe Pnj
*/
        ~Pnj();

         /*! \fn string getName()
\brief Retourne le nom du Pnj
\return Valeur de name
*/
        string getName();

          /*! \fn string getSurname()
\brief Retourne le prénom du Pnj
\return Valeur de surname
*/
        string getSurname();

          /*! \fn Sprite getPnjHead()
\brief Retourne le sprite représentant l'apparence du Pnj
\return Contenu de pnjHead
*/
        Sprite getPnjHead();

      /*! \fn Sprite getPnjMovement()
\brief Retourne le sprite représentant les mouvements du Pnj
\return Contenu de pnjMovement
*/
        Sprite getPnjMovement();

          /*! \fn int getPositionX()
\brief Retourne la position X du Pnj
\return Poisition X de Pnj
*/
        int getPositionX();

                  /*! \fn int getPositionY()
\brief Retourne la position Y du Pnj
\return Poisition Y de Pnj
*/
        int getPositionY();

/*! \fn void setName(strinf n)
\brief Modifie le nom du personnage
\param n - Nouveau nom du personnage
*/
        void setName(string n);

        /*! \fn void setSurname(strinf s)
\brief Modifie le prénom du personnage
\param n - Nouveau prénom du personnage
*/
        void setSurname(string s);

        /*! \fn void setImgPnjHead(strinf s)
\brief Modifie l'image qui représente l'apparence du Pnj, et lie les sprite pnjHead a cette image.
\param s - lien vers l'image de l'apparence du Pnj
*/
        void setImgPnjHead(string s);

        /*! \fn void setImgPnjMovement(strinf s)
\brief Modifie l'image qui représente les mouvements du Pnj, et lie les sprite pnjMovement a cette image.
\param s - lien vers l'image de l'apparence du Pnj
*/
        void setimgPnjMovement(string s);

        /*! \fn void setPosition(int x, int y)
\brief Modifie la position du Pnj
\param x - nouvelle position X du Pnj
\param y : nouvelle position Y du Pnj
*/
        void setPosition(int x, int y);

/*! \fn void askAnim(int d)
\brief Appelle le Thread de mouvement si le personnage peut bouger. Enregistre la direction dans Anim.
La préocèdure appelle les Thread de déplacement si isMoving est a false, qui signifie que le Pnj n'est pas déjà en cours de déplacement.
\param d - direction du mouvement (compris entre 0 et 4, voir var_define.h)
*/
        bool askAnim(int d, bool moveOn);
        bool getIsMoving();
        void setIsMoving(bool b);

        void setCanMove(bool c) {canMove = c;}

        int getCaseX();
        int getCaseY();

        int getDestCaseX();
        int getDestCaseY();

        void rotate(int d);
        int getDirection();

        void setHeadPosition(int i, int j);


};

#endif
